﻿// Defines an HTML wrapper element that can have children ones
define([
    'Wjs/Wjs'
],
function () {
    'use strict';

    return Wjs.defineOnce({

        type: 'CssStyles',

        internal: {

            construct: function () {

                // The style to be applied to the DOM element when it is created
                this.style = {};
            },

            // Events handler

            listeners: {

                onDomElementCreated: function () {

                    // Apply the style to the DOM element
                    this.setStyle(this.style);
                },

                onCloned: function (cloned) {

                    this.copyCssStylesTo(cloned);
                }
            }

        },

        // Set a property of the style object
        setStyleProperty: function (name, value) {
            var oldValue = this.getStyleProperty(name);

            if (oldValue) {

                Wjs.log('debug', 'Replacing style property of name: ' + name + ' and value: ' + oldValue + ' with value: ' + value)
            }

            if (this.isRendered()) {

                this.getDomElement().style[name] = value;
            }
            else {

                this.style[name] = value;
            }

            return this;
        },

        // Retrieves a property of the style object
        getStyleProperty: function (name) {

            if (this.isRendered()) {

                return this.getDomElement().style[name];
                // or return this.getDomElement().style.getPropertyValue(name);
            }
            else {

                return this.style[name];
            }
        },

        // Removes a property of the style object
        removeStyleProperty: function (name) {

            if (this.isRendered()) {

                this.getDomElement().style.removeProperty(name);
            }
            else {

                delete this.style[name];
            }

            return this;
        },

        // Sets the style of the element
        setStyle: function (style) {
            var value;

            for (var name in style) {

                value = style[name];

                this.setStyleProperty(name, value);
            }

            return this;
        },

        getStyle: function () {

            if (this.isRendered()) {

                return this.getComputedStyle();
            }
            else {

                return this.style;
            }
        },

        getComputedStyle: function (pseudoElement) {

            if (!this.isRendered()) {

                throw 'getComputedStyle requires the element to be rendered';
            }

            return window.getComputedStyle(this.getDomElement(), pseudoElement);
        },

        copyCssStylesTo: function (view) {

            view.setStyle(this.getStyle());
        },

        //#region Dimension manipulations

        getClientWidth: function () {

            if (!this.isRendered()) {

                throw 'getClientWidth requires the element to be rendered';
            }

            return this.getDomElement().clientWidth;
        },

        getClientHeight: function () {

            if (!this.isRendered()) {

                throw 'getClientHeight requires the element to be rendered';
            }

            return this.getDomElement().clientHeight;
        },

        getOffsetWidth: function () {

            if (!this.isRendered()) {

                throw 'getOffsetWidth requires the element to be rendered';
            }

            return this.getDomElement().offsetWidth;
        },

        getOffsetHeight: function () {

            if (!this.isRendered()) {

                throw 'getOffsetHeight requires the element to be rendered';
            }

            return this.getDomElement().offsetHeight;
        },

        // Setting and getting the dimensions of the view
        setLeft: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('left', value);

            return this;
        },

        getLeft: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetLeft;
            }

            return this.getStyleProperty('left');
        },

        setRight: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('right', value);

            return this;
        },

        getRight: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetLeft + this.getDomElement().offsetWidth;
            }

            return this.getStyleProperty('right');
        },

        setTop: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('top', value);

            return this;
        },

        getTop: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetTop;
            }

            return this.getStyleProperty('top');
        },

        setBottom: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('bottom', value);

            return this;
        },

        getBottom: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetTop + this.getDomElement().offsetHeight;
            }

            return this.getStyleProperty('bottom');
        },

        setWidth: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('width', value);

            return this;
        },

        getWidth: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetWidth;
            }

            return this.getStyleProperty('width');
        },

        setHeight: function (value) {

            if (Wjs.isNumber(value)) {

                value = value + 'px'; // Default to pixels if the value is numeric
            }

            this.setStyleProperty('height', value);

            return this;
        },

        getHeight: function () {

            if (this.isRendered()) {

                return this.getDomElement().offsetHeight;
            }

            return this.getStyleProperty('height');
        },

        getRectangle: function () {

            if (!this.isRendered()) {

                throw 'getRectangle requires the element to be rendered';
            }

            if (this.getStyleProperty('display') == 'none') {

                throw 'getRectangle requires the element to be visible (display is none)';
            }

            return this.getDomElement().getBoundingClientRect();
        }

        //#endregion

    });

});